package pf.springBoot.springBootSSO.controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.JSON;
import com.perfect99.right.amsweb.ActionReturnInfo;
import com.perfect99.right.amsweb.BaseReturnInfo;

import pf.java.pfHelper.AbstractApiResult;
import pf.java.pfHelper.PFAllowAnonymous;
import pf.java.pfHelper.PFCaching;
import pf.java.pfHelperNotSpring.PFDataRow;
import pf.java.pfHelperNotSpring.PFDataTable;
import pf.java.pfHelper.PFJsonData;
import pf.java.pfHelper.PFJsonDataT;
import pf.java.pfHelper.PFObject;
//import pf.java.pfHelper.PFObject;
import pf.java.pfHelperNotSpring.PFRef;
import pf.java.pfHelper.config.PFDataHelper;
import pf.java.pfHelper.model.SystemUser;
import pf.java.pfHelper.model.UserOrg;
import pf.java.pfHelper.model.UserTypeClass;
import pf.springBoot.springBootSSO.controller.shares.YJQueryController;
import pf.springBoot.springBootSSO.oAuth.FormsAuth;
import pf.springBoot.springBootSSO.oAuth.LoginerBase;
import pf.springBoot.springBootSSO.oAuth.MetabaseDataHelper;
import pf.springBoot.springBootSSO.oAuth.MetabaseFormsAuth;
import pf.springBoot.springBootSSO.oAuth.MetabaseUser;
import pf.springBoot.springBootSSO.oAuth.model.*;
import pf.springBoot.springBootSSO.projHelper.DES_IV;
import pf.springBoot.springBootSSO.service.BalanceService;

//@RestController
@Controller
//@RequestMapping("/User")
public class UserController extends  YJQueryController
{
    @Autowired
    private BalanceService _balanceService;
//    //阻止分公司
//    public static bool PreventFgs
//    {
//        get
//        {
//            return ConfigurationManager.AppSettings["PreventFgs"] != null && bool.Parse(ConfigurationManager.AppSettings["PreventFgs"]);
//        }
//    }
//    @Autowired
//    private HttpServletResponse response;
//    public UserController()
//    {
//        //_balanceService = new BalanceService();//这句有问题--benjamin todo
//    }
//    @GetMapping("/User/Login")
//    public ModelAndView Login()
//    {
//        return View("User/Login");
//    }

    @PFAllowAnonymous
  	@GetMapping(value = "/User/LoginMetabase")
    public ModelAndView LoginMetabase(String return_to)
    {
    	ViewData.clear();
    	//注意不要在这里加SSO自动登陆,因为metabase退出时不会退出sso,如果加了,就永远都会是自动登陆了
        return super.View((Object)return_to);
    }

    @PFAllowAnonymous
  	@PostMapping(value = "/User/LoginMetabase")
    public ModelAndView LoginMetabase(String userid, String password, String return_to)
    {
  		//BaseReturnInfo user = FormsAuth.LoginCheck(userid, password);
  		BaseReturnInfoDto user = FormsAuth.LoginCheckWebApi(userid, password);
        if (!user.isIsSuccess())
        {
            ViewData.put("err","用户名或密码错误");
            return View((Object)return_to);
        }
        else
        {
            String url = MetabaseDataHelper.GetSsoJwtUrl(
                MetabaseFormsAuth.GetMetabaseUser(userid),
                return_to
                );

            return super.RedirectToUrl(url);
        }
    }
    
    @PFAllowAnonymous
  	@GetMapping(value = "/User/AutoLoginMetabase")
    public ModelAndView AutoLoginMetabase(String userid, String return_to)
    {
        MetabaseUser metabaseUser = MetabaseFormsAuth.GetMetabaseUser(userid);
        if (metabaseUser == null)
        {
            return  super.Json(PFJsonData.SetFault("用户不存在")//, JsonRequestBehavior.AllowGet
            		);

        }

        String url = MetabaseDataHelper.GetSsoJwtUrl(
            metabaseUser,
            return_to
            );
        return super.RedirectToUrl(url);
    }
    
/*
 * 便于其它系统想只拿token的
 */
    @PFAllowAnonymous
  	@GetMapping(value = "/User/GetMetabaseToken")
    @ResponseBody
    public String GetMetabaseToken(String userid)
    {
        MetabaseUser metabaseUser = MetabaseFormsAuth.GetMetabaseUser(userid);
        if (metabaseUser == null)
        {
        	return JSON.toJSONString(AbstractApiResult.error("用户不存在"));
//            return  super.Json(PFJsonData.SetFault("用户不存在")//, JsonRequestBehavior.AllowGet
//            		);
////        	return Json();
////            ModelAndView mav = new ModelAndView(new MappingJackson2JsonView());  
////            mav.addObject("result", "failed");  
////            return mav;  
        }

        String token=MetabaseDataHelper.SignUserToken(metabaseUser);
        return token;
    }

/*
 * 所有系统的单点登陆控制，如果用户已在本系统登陆，直接返回token
 */
    @PFAllowAnonymous
  	@GetMapping(value = "/User/AuthSSO")
    public ModelAndView AuthSSO(String return_to,@RequestParam(required = false) String login_url)
    {
    	PFRef<SystemUser> userDataRef=new PFRef<SystemUser>();
    	Boolean isLogin= FormsAuth.IsUserLogined(userDataRef);
    	
//    	SystemUser userData = FormsAuth.GetUserExData(SystemUser.class);
//        Boolean isLogin=!(userData == null || PFDataHelper.StringIsNullOrWhiteSpace(userData.UserCode));
    	
    	if(isLogin) {//UserAuthorizeAttribute.IsLogined()
    		SystemUser userData=userDataRef.GetValue();
            String token=FormsAuth.SignUserToken(userData);
//            ModelAndView mav = new ModelAndView(new MappingJackson2JsonView());
//            mav.addObject(token);
            HashMap<String, Object> urlParam = new HashMap<String, Object>() {
				private static final long serialVersionUID = 1L;

				{
                    put("token", token);
                }
            };
            //return super.RedirectToUrl(return_to+"&token="+token);
 	       String rUrl=PFDataHelper.setUrlParams(return_to,urlParam);
 	       if(!rUrl.startsWith("http")) {rUrl="http://"+rUrl;}
           return super.RedirectToUrl(rUrl);
            //return super.RedirectToUrl(PFDataHelper.setUrlParams(return_to,urlParam));
    	}
    	if(login_url!=null) {
 	       String rUrl=login_url;
  	       if(!rUrl.startsWith("http")) {rUrl="http://"+rUrl;}
            return super.RedirectToUrl(rUrl);
    	}else {
            return super.RedirectToUrl("/User/LoginSSO?return_to="+return_to);
    	}
    	//可以考虑连同Metabase一起登陆
    }

/*
 * 登陆页面(其它系统可共用)
 */
    @PFAllowAnonymous
  	@GetMapping(value = "/User/LoginSSO")
    public ModelAndView LoginSSO(@RequestParam(required = false) String return_to,@RequestParam(required = false) String error )
    {
    	ViewData.clear();
    	if(error!=null) {
            ViewData.put("err",error);
    	}
        return super.View((Object)return_to);
    }

    /*
     * 登陆方法(其它系统可共用)
     */
    @PFAllowAnonymous
  	@GetMapping(value = "/User/GoLoginSSO")
    public ModelAndView GoLoginSSO(String userid, String password, String return_to,@RequestParam(required = false) String login_url)
    {
  		//BaseReturnInfo user = FormsAuth.LoginCheck(userid, password);
  		BaseReturnInfoDto user = FormsAuth.LoginCheckWebApi(userid, password);
        if (!user.isIsSuccess())
        {
        	if(login_url!=null) {
               HashMap<String, Object> urlParam = new HashMap<String, Object>() {
   				private static final long serialVersionUID = 1L;

   				{
                       put("error", PFDataHelper.getURLEncoderString("帐号或密码不正确(SSO)"));
                   }
               };
               //aaabbbcc
               //return super.RedirectToUrl(return_to+"&token="+token);
    	       String rUrl=PFDataHelper.setUrlParams(login_url,urlParam);
       	       if(!rUrl.startsWith("http")) {rUrl="http://"+rUrl;}
                 return super.RedirectToUrl(rUrl);
         	}else {
//                 return super.RedirectToUrl("/User/LoginSSO?return_to="+return_to);
                 //ViewData.put("err","用户名或密码错误");
//                 return View((Object)return_to,"/User/LoginSSO");
                 return super.RedirectToUrl("/User/LoginSSO?return_to="+return_to+"&error="+PFDataHelper.getURLEncoderString("用户名或密码错误"));
         	}
        }
        else
        {
            Boolean b;
            String error;
            PFRef<Boolean> rB = new PFRef<Boolean>(false);
            PFRef<String> rError = new PFRef<String>(null);
            PFRef<SystemUser> rSysUser= new PFRef<SystemUser>(null);
            
           // List<String> fgsList=
            		DoSignIn(user,rB, rError,rSysUser);
            		
            b=rB.GetValue();
            error=rError.GetValue();
            if (!b)
            {
                ViewData.put("err",error);
                return View((Object)return_to);
                //return PFJsonData.SetFault(error);
            }
//        	SystemUser userData = FormsAuth.GetUserExData(SystemUser.class);//刚登陆完不能用此方法，因为request里还没有cookie
        	SystemUser userData =rSysUser.GetValue();
        	userData.Pwd=password;
            String token=FormsAuth.SignUserToken(userData);
//          ModelAndView mav = new ModelAndView(new MappingJackson2JsonView());
//          mav.addObject(token);
	          HashMap<String, Object> urlParam = new HashMap<String, Object>() {
				private static final long serialVersionUID = 1L;

				{
	                  put("token", token);
	              }
	          };
          //return super.RedirectToUrl(return_to+"&token="+token);
	          
	       if(PFDataHelper.StringIsNullOrWhiteSpace(return_to)) {
		          return super.Json(AbstractApiResult.success("登陆成功，但没有指定return_to页面"));
	       }else {
		       String rUrl=PFDataHelper.setUrlParams(return_to,urlParam);
	 	       if(!rUrl.startsWith("http")) {rUrl="http://"+rUrl;}
	          return super.RedirectToUrl(rUrl);
	       }

        }
    }

    @PFAllowAnonymous
  	@GetMapping(value = "/User/GoLoginSSOUserId")
    public ModelAndView GoLoginSSOUserId(String userid, String return_to,@RequestParam(required = false) String login_url)
    {
  		//BaseReturnInfo user = FormsAuth.LoginCheck(userid, password);
  		//BaseReturnInfoDto user = FormsAuth.LoginCheckWebApi(userid, password);
  		BaseReturnInfoDto user =new BaseReturnInfoDto(FormsAuth.GetAllAction(new DES_IV().decode(userid)));
  		//UserAllInfoDto user =FormsAuth.GetUserInfoWebApi(userid);
        if (!user.isIsSuccess())
        {
        	if(login_url!=null) {
               HashMap<String, Object> urlParam = new HashMap<String, Object>() {
   				private static final long serialVersionUID = 1L;

   				{
                       put("error", "帐号或密码不正确(SSO)");
                   }
               };
               //return super.RedirectToUrl(return_to+"&token="+token);
    	       String rUrl=PFDataHelper.setUrlParams(login_url,urlParam);
       	       if(!rUrl.startsWith("http")) {rUrl="http://"+rUrl;}
                 return super.RedirectToUrl(rUrl);
         	}else {
//                 return super.RedirectToUrl("/User/LoginSSO?return_to="+return_to);
                 //ViewData.put("err","用户名或密码错误");
//                 return View((Object)return_to,"/User/LoginSSO");
                 return super.RedirectToUrl("/User/LoginSSO?return_to="+return_to+"&error="+PFDataHelper.getURLEncoderString("用户名或密码错误"));
         	}
        }
        else
        {
            Boolean b;
            String error;
            PFRef<Boolean> rB = new PFRef<Boolean>(false);
            PFRef<String> rError = new PFRef<String>(null);
            PFRef<SystemUser> rSysUser= new PFRef<SystemUser>(null);
            
           // List<String> fgsList=
            		DoSignIn(user,rB, rError,rSysUser);
            		
            b=rB.GetValue();
            error=rError.GetValue();
            if (!b)
            {
                ViewData.put("err",error);
                return View((Object)return_to);
                //return PFJsonData.SetFault(error);
            }
//        	SystemUser userData = FormsAuth.GetUserExData(SystemUser.class);//刚登陆完不能用此方法，因为request里还没有cookie
        	SystemUser userData =rSysUser.GetValue();
        	userData.Pwd="autologin";
            String token=FormsAuth.SignUserToken(userData);
//          ModelAndView mav = new ModelAndView(new MappingJackson2JsonView());
//          mav.addObject(token);
	          HashMap<String, Object> urlParam = new HashMap<String, Object>() {
				private static final long serialVersionUID = 1L;

				{
	                  put("token", token);
	              }
	          };
          //return super.RedirectToUrl(return_to+"&token="+token);
	          
	       if(PFDataHelper.StringIsNullOrWhiteSpace(return_to)) {
		          return super.Json(AbstractApiResult.success("登陆成功，但没有指定return_to页面"));
	       }else {
		       String rUrl=PFDataHelper.setUrlParams(return_to,urlParam);
	 	       if(!rUrl.startsWith("http")) {rUrl="http://"+rUrl;}
	          return super.RedirectToUrl(rUrl);
	       }

        }
    }

	@PFAllowAnonymous
  	@GetMapping(value = "/User/LogoutSSO")
    public ModelAndView LogoutSSO(String return_to) {
	       FormsAuth.SingOut();
	       
	       if(PFDataHelper.StringIsNullOrWhiteSpace(return_to)) {
	            return super.RedirectToUrl("/User/LoginSSO");
		        //return super.Json(AbstractApiResult.success("退出成功，但没有指定return_to页面"));
	       }else {
	           String rUrl=return_to;
		       if(!rUrl.startsWith("http")) {rUrl="http://"+rUrl;}		       
	           return super.RedirectToUrl(rUrl);
	       }

    }
  //无论是@RestController还是@Controller都不影响返回页面
  	@PostMapping(value = "/User/PostLogin")
  	public ModelAndView PostloginPage(String userid,String password
//  			,
//  			HttpServletRequest request,HttpServletResponse response
  			){
      if (DoCheckLogin(userid, password).Result)//这里有报错--benjamin todo
      {
    		return super.RedirectToUrl("/");
//    	  try {
//			response.sendRedirect("/");
//		} catch (IOException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
//    	  return null;
    	  
//      	//response.sendRedirect("/User/Login");
//    	  return new ModelAndView("redirect:/");
//          return new ModelAndView("redirect:/");
//          //return "redirect:/target";
          //return View("User/Login");
      }else {
    	  return View("User/Login");
      }
		
	  //return new ModelAndView("redirect:/");
	  
//      //ok
//  		return new ModelAndView("redirect:/");
  		
//	  ////ok
//  		ViewData.put("err", "密码错误");
//      return View("User/Login");
  		
//  		ModelAndView mav = new ModelAndView();
//  		mav.addObject("wvp",new WebViewPageT<Object>(this));
//  		mav.addObject("Html",new HtmlHelper());
//  		mav.setViewName("User/Login");
//  		
//  		return mav;
  	}


    

//    private List<String> DoSignIn(BaseReturnInfo user ,PFRef<Boolean>  success,PFRef<String>   error,PFRef<SystemUser> refSysUser)
    private List<String> DoSignIn(BaseReturnInfoDto user ,PFRef<Boolean>  success,PFRef<String>   error,PFRef<SystemUser> refSysUser) 
    {
        //error = null;
        error.SetValue(null);
        //var userid = user.UserId;
        String userid = user.getUserNumber();
        LoginerBase userData = new LoginerBase();
        userData.UserCode=userid;
        userData.UserName=user.getUserName();

        int effectiveHours = 1;//登陆1小时
        //UserAllInfo userAllInfo = FormsAuth.GetUserInfo(userid);
        UserAllInfoDto userAllInfo = FormsAuth.GetUserInfoWebApi(userid);
        SystemUser sysUser = new SystemUser();
        refSysUser.SetValue(sysUser);
    	sysUser.UserCode=userid;
    	sysUser.UserName=user.getUserName();
    	sysUser.Email=userAllInfo.getEMail();
    			
    	List<String> fgsList = new ArrayList<String>();

        PFDataTable fgsTable=null;

        String precinct = user.getPrecinct()==null?"":user.getPrecinct();
        String orgNumber = user.getOrgExtNumber()==null? user.getOrgNumber():user.getOrgExtNumber();
        //String orgName = user.getOrgName();

        ArrayList<UserOrg> orgList = new ArrayList<UserOrg>();
        if (PFDataHelper.StringIsNullOrWhiteSpace(user.getOrgExtNumber()))
        {
        	UserOrg userOrg=new UserOrg();
        	userOrg.Org = user.getOrgNumber();
        	userOrg.OrgName = user.getOrgName();
        	userOrg.UserType = UserTypeClass.Default;
            orgList.add(userOrg);
        }else
        {
        	UserOrg userOrg=new UserOrg();
        	userOrg.Org = user.getOrgExtNumber();
        	userOrg.OrgName = user.getOrgName();
        	userOrg.UserType = UserTypeClass.Fgs;
            orgList.add(userOrg);
        }
        fgsList =Arrays.asList(precinct.split(",")).stream().filter(a->a!=orgNumber).collect(Collectors.toList());
        for(String fgs : fgsList)
        {
            fgsTable = _balanceService.GetSFByFgs(fgs);//benjamin
            //fgsTable = new BalanceService().GetSFByFgs(fgs);//benjamin 
            
            if (fgsTable != null && !fgsTable.IsEmpty())
            {
                PFDataRow row = fgsTable.getRow().get(0);
            	UserOrg userOrg=new UserOrg();
            	userOrg.Org = row.getStringColumn("fgs");
            	userOrg.OrgName = row.getStringColumn("fgsname");
            	userOrg.UserType = UserTypeClass.Fgs;
                orgList.add(userOrg);
            }             
        }
        if (orgList.size() > 0)
        {
        	if(orgList.get(0).UserType==UserTypeClass.Fgs) {
                fgsTable = _balanceService.GetSFByFgs(orgList.get(0).Org);//benjamin 
                //fgsTable =  new BalanceService().GetSFByFgs(orgList.get(0).Org);//benjamin 
            	PFDataRow row = fgsTable.getRow().get(0);
                sysUser.Sf = row.getStringColumn("sf");
                sysUser.SfName = row.getStringColumn("sfname");
                sysUser.Fgs = row.getStringColumn("fgs");
                sysUser.FgsName = row.getStringColumn("fgsname");
        	}
//            switch (orgList.get(0).UserType.getValue())
//            {
//                case UserTypeClass.Fgs.getValue():
//                    fgsTable = _balanceService.GetSFByFgs(orgList.get(0).Org);
//                	PFDataRow row = fgsTable.getRow().get(0);
//                    sysUser.Sf = row.getStringColumn("sf");
//                    sysUser.SfName = row.getStringColumn("sfname");
//                    sysUser.Fgs = row.getStringColumn("fgs");
//                    sysUser.FgsName = row.getStringColumn("fgsname");
//                    break;
//                default:
//                    break;
//            }
            sysUser.Org = orgList.get(0).Org;
            sysUser.OrgName = orgList.get(0).OrgName;
        }

        sysUser.OrgList = orgList;


        if (PFDataHelper.PreventFgs() && (!PFDataHelper.StringIsNullOrWhiteSpace(sysUser.Sf)))
        {
            success.SetValue(false);
            error.SetValue("已坏");
            return new ArrayList<String>();
        }
        FormsAuth.SignIn(userData, sysUser, 60 * effectiveHours);
        success.SetValue(true);
        return fgsList;

    }
    private PFJsonData DoCheckLogin(String userid, String password)
    {
//        //OAuthClientManager manager = new OAuthClientManager();
//        //TokenInfo token = manager.LoginCheck(userid, password);
//        //if (token == null) { return View(token); }else{token.Refresh();Token = token;}
//    	BaseReturnInfo user = FormsAuth.LoginCheck(userid, password);
    	BaseReturnInfoDto user = FormsAuth.LoginCheckWebApi(userid, password);
        if (!user.isIsSuccess())
        {
            ViewData.put("err","用户名或密码错误");
            return PFJsonData.SetFault("用户名或密码错误");
        }
        else
        {
            Boolean b;
            String error;
            PFRef<Boolean> rB = new PFRef<Boolean>(false);
            PFRef<String> rError = new PFRef<String>(null);
            PFRef<SystemUser> rSysUser= new PFRef<SystemUser>(null);
            List<String> fgsList=DoSignIn(user,rB, rError,rSysUser);
            b=rB.GetValue();
            error=rError.GetValue();
            if (!b)
            {
                ViewData.put("err",error);
                return PFJsonData.SetFault(error);
            }

            return new PFJsonDataT<Object>().SetSuccess(new PFObject()
               .Add("userInfo", 
            		   new PFObject()
            		   .Add("userId", GetUserId())
            		   .Add("userName", GetUserName())
            		   .Add("sf", GetSf())
            		   .Add("sfname", GetSfName())
            		   .Add("fgs", GetFgs())
            		   .Add("fgsname", GetFgsName())
            		   .Add("fgsList", fgsList)            		   
        		   )
//               .Add("session",PFCookieUtils.getCookieMap()) //benjamin todo
            );
        }
    }
//
  	@PostMapping(value = "/User/Logout")
  	@ResponseBody
    public PFJsonData Logout()
    {
        String UserId=GetUserId();
        if (!PFDataHelper.StringIsNullOrWhiteSpace(UserId))
        {
            PFCaching.Remove(UserId);
            //Sf = null;
            //SfName = null;
            //Fgs = null;
            //FgsName = null;
            //CurrentMonth = null;
            //CurrentDatabase = null;
            FormsAuth.SingOut();

            rdto = PFJsonData.SetSuccess();
        }
        else
        {
            rdto = PFJsonData.SetSuccess("未登陆");
        }
        return rdto;
    }
//
//    /// <summary>
//    /// 设置当前分公司(机构)
//    /// </summary>
//    /// <returns></returns>
//    [HttpPost]
//    public ActionResult SetOrg(string org,string orgName)
//    {
//        var sysUser = SystemUser ?? new SystemUser();
//        var fgsTable = _balanceService.GetSFByFgs(org);
//        if (fgsTable != null && fgsTable.Rows.Count > 0)
//        {
//            sysUser.Sf = fgsTable.Rows[0]["sf"].ToString();
//            sysUser.SfName = fgsTable.Rows[0]["sfname"].ToString();
//            sysUser.Fgs = fgsTable.Rows[0]["fgs"].ToString();
//            sysUser.FgsName = fgsTable.Rows[0]["fgsname"].ToString();
//
//        }else
//        {
//            sysUser.Sf = null;
//            sysUser.SfName = null;
//            sysUser.Fgs = null;
//            sysUser.FgsName = null;
//        }
//        sysUser.Org = org;
//        sysUser.OrgName = orgName;
//        SystemUser = sysUser;
//        rdto = JsonData.SetSuccess();
//        return Json(rdto);
//    }
//
//    public ActionResult ForgetPassword() {
//        return View();
//    }
}